﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.Composite.Presentation.Events;
using VisualStock.Infrastructure;
using VisualStock.Infrastructure.Interfaces;
using VisualStock.Infrastructure.Models;

namespace VisualStock.Modules.StockSymbols.ComparingSymbols
{
    public partial class ComparingSymbolListViewModel : IComparingSymbolListViewModel
    {
        #region Private Fields

        private readonly IHistoricalDataService historicalDataService;

        private readonly IComparingSymbolService comparingSymbolService;

        private IEventAggregator eventAggregator { get; set; }

        private ObservableCollection<string> _comparingSymbolList = new ObservableCollection<string>();

        private ObservableCollection<string> _selectedSymbolList = new ObservableCollection<string>();

        private DelegateCommand<object> _compareCommand;

        private DelegateCommand<object> _removeCommand;

        private DelegateCommand<string> _addCommand;

        private ObservableSymbolCollection _downloadList = new ObservableSymbolCollection();

        #endregion

        public ObservableSymbolCollection DownloadList
        {
            get { return _downloadList; }
            set { _downloadList = value; }
        }

        public ComparingSymbolListViewModel(IHistoricalDataService historicalDataService, IComparingSymbolService comparingSymbolService, IComparingSymbolListView view, IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            this.eventAggregator.GetEvent<HistoricalDataDownloadStatusChanged>().Subscribe(RefreshDownloadList, ThreadOption.UIThread);
            this.historicalDataService = historicalDataService;
            this.comparingSymbolService = comparingSymbolService;
            this.comparingSymbolService.AvailableSymbolChanged += new EventHandler<AvailableSymbolChangedEventArgs>(ComparingSymbolService_AvailableSymbolChanged);
            this.View = view;
            this.View.Model = this;

            _selectedSymbolList.CollectionChanged += (e, s) =>
                {
                    // Publish the event only when single symbol was selected
                    if (_selectedSymbolList.Count == 1)
                        this.eventAggregator.GetEvent<SelectedSymbolChangedEvent>().Publish(_selectedSymbolList[0]);
                };
        }

        public void RefreshDownloadList(ObservableSymbolItem item)
        {
            if (item.DownloadStatus == SymbolDownloadStatus.Downloading)
                this.DownloadList.Add(item);
            else this.DownloadList.Remove((from ditem in DownloadList where ditem.Symbol == item.Symbol select ditem).Single<ObservableSymbolItem>());
        }

        private void ComparingSymbolService_AvailableSymbolChanged(object sender, AvailableSymbolChangedEventArgs e)
        {
            if (e.NewItems != null)
                foreach (string item in e.NewItems)
                    _comparingSymbolList.Add(item);

            if (e.OldItems != null)
                foreach (string item in e.OldItems)
                    _comparingSymbolList.Remove(item);
        }

        private bool CanAddExcuted(string newComparingSymbol)
        {
            if (_comparingSymbolList.Contains(newComparingSymbol) || String.IsNullOrEmpty(newComparingSymbol) || newComparingSymbol.Contains('_'))
                return false;
            return true;
        }

        private void OnCompareExcuted(object parameter)
        {
            this.eventAggregator.GetEvent<NewComparisonRequestedEvent>().Publish(_selectedSymbolList.ToList<string>());
        }

        private void OnRemoveExcuted(object parameter)
        {
            this.comparingSymbolService.RemoveSymbols(_selectedSymbolList.ToList<string>());
        }

        #region IComparingSymbolListPresentationModel Members

        public IComparingSymbolListView View { get; set; }

        /// <summary>
        /// The list of symbols which can be added to the SelectedSymbolList
        /// </summary>
        public ObservableCollection<string> ComparingSymbolList
        {
            get { return _comparingSymbolList; }
        }

        /// <summary>
        /// The list of symbols which are selected to display in the chart
        /// </summary>
        public ObservableCollection<string> SelectedSymbolList
        {
            get { return _selectedSymbolList; }
            set { _selectedSymbolList = value; }
        }

        public DelegateCommand<object> CompareCommand
        {
            get
            {
                if (_compareCommand == null)
                {
                    _compareCommand = new DelegateCommand<object>(OnCompareExcuted);
                }
                return _compareCommand;
            }
        }

        public DelegateCommand<object> RemoveCommand
        {
            get
            {
                if (_removeCommand == null)
                {
                    _removeCommand = new DelegateCommand<object>(OnRemoveExcuted);
                }
                return _removeCommand;
            }
        }

        public DelegateCommand<string> AddCommand
        {
            get
            {
                if (_addCommand == null)
                {
                    _addCommand = new DelegateCommand<string>(OnAddExcuted, CanAddExcuted);
                }
                return _addCommand;
            }
        }

        #endregion
    }
}
